﻿#pragma once
#ifndef WRWORKDEVICE_H
#define WRWORKDEVICE_H

#include "WRGlobal.h"
#include "WRWorkDriver.h"
#include "Structs/WRWorkStatus.h"
#include "Structs/WRWorkSwitch.h"
#include "../WRSoft-Utility/Runtime/WRType.h"
#include "../WRSoft-Utility/Framing/WRTaskDealer.h"
#include "../WRSoft-Utility/Framing/WRDataSource.h"
#include "../WRSoft-Utility/Framing/WREventSource.h"
#include "../WRSoft-Utility/Framing/WRStateSource.h"
#include "../WRSoft-Utility/Framing/WRStateHandlers.h"

//表示工作设备。
class WRSOFT_WORKING_COMMON_CLASS WRWorkDevice : public WRWorkEntity
{
    friend class WRWorkDriver;

public:
    //获取当前工作设备类型。
    virtual WRType* type(void) const = 0;

    //查询指定标识的任务处理者。
    virtual WRTaskDealer* queryTaskDealer(const QUuid& uuid);
    //查询指定标识的数据源接口。
    virtual WRDataSource* queryDataSource(const QUuid& uuid);
    //查询指定标识的事件源接口。
    virtual WREventSource* queryEventSource(const QUuid& uuid);
    //查询指示标识的状态源接口。
    virtual WRStateSource* queryStateSource(const QUuid& uuid);

    //打开设备，如果成功，则返回0。
    virtual WR32s open(void) = 0;
    //启动工作，如果成功，则返回0。
    virtual WR32s start(void) = 0;
    //停止工作。
    virtual void stop(void) = 0;
    //关闭设备。
    virtual void close(void) = 0;

private:
    //执行切换处理。
    inline WR32s doSwitch(WRWorkSwitch& task)
    {
        WRWorkSwitch::Action action = task.action();
        switch(action)
        {
            case WRWorkSwitch::Open:
                return open();
            case WRWorkSwitch::Start:
                return start();
            case WRWorkSwitch::Stop:
                stop();
                return WRErrors::None;
            case WRWorkSwitch::Close:
                close();
                return WRErrors::None;
            default:
                return WRErrors::ArgumentOutOfRange;
        }
    }

    //表示状态处理器集合。
    class StatusHandlers : public WRStateHandlers<WRWorkStatus>
    {
    public:
        //初始化状态处理器。
        inline StatusHandlers(void)
            : WRStateHandlers<WRWorkStatus>(WRWorkStatus::Closed)
        {
            //add code here
        }
    };
    //表示切换处理者类。
    WRTASKDEALER(SwitchDealer, WRWorkSwitch, WRWorkDevice, doSwitch)

    //所属驱动。
    WRWorkDriver* m_driver;
    //切换处理者。
    SwitchDealer m_switchDealer;
    //状态处理器集合。
    StatusHandlers m_statusHandlers;

    //禁用复制构造函数和赋值操作符。
    Q_DISABLE_COPY(WRWorkDevice)

protected:
    //当状态改变后调用此方法。
    inline void onStatusChanged(WRWorkStatus value)
    {
        m_statusHandlers.doProcess(value);
    }

    //初始化工作设备。
    WRWorkDevice(const WRWorkInformation& info, WRWorkDriver* driver);
    //当前对象所占用的相关资源。
    ~WRWorkDevice(void);

    //获取设备的当前状态。
    inline WRWorkStatus status(void) const
    {
        return m_statusHandlers.value();
    }

public:
    //添加对象引用。
    inline void addRef(void)
    {
        m_driver->addRef();
    }
    //释放对象引用, 如果引用计数为0，则删除对象，返回True，否则返回False。
    inline bool release(void)
    {
        return m_driver->release();
    }

    //获取当前设备所属的驱动。
    inline WRWorkDriver* driver(void) const
    {
        return m_driver;
    }

    //获取当前设备所属的工作进程。
    inline WRWorkDaemon* daemon(void) const
    {
        return m_driver->daemon();
    }

    //识别当前设备是否是指定类型标识设备的实例。
    inline bool identify(const QUuid& tuid) const
    {
        WRType* type = this->type();
        while(type)
        {
            if (type->uuid() == tuid)
            {
                return true;
            }
            type = type->base();
        }
        return false;
    }
    //识别当前设备是否是指定类型设备的实例。
    inline bool identify(WRType* type) const
    {
        if (type)
        {
            WRType* type2 = this->type();
            while(type2)
            {
                if (type2 == type)
                {
                    return true;
                }
                type2 = type2->base();
            }
        }
        return false;
    }

    //获取切换处理者。
    inline WRTaskDealer* switchDealer(void)
    {
        return &m_switchDealer;
    }
    //获取状态源。
    inline WRStateSource* statusSource(void)
    {
        return &m_statusHandlers;
    }
};

#endif // WRWORKDEVICE_H
